/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021.
 * Description: enable/disable sending notify when vm expand to the threshold.
 * Author: chengchao
 * Create: 2021-03-17
 */
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/rtos/ulimit.h>

static struct kobject *ulimit_kobj;

static ssize_t show(struct kobject *kobj, struct kobj_attribute *attr,
			char *buf)
{
	return snprintf(buf, 10, "%lu\n", vm_expand_signal_enable);
}

static ssize_t store(struct kobject *kobj, struct kobj_attribute *attr,
			const char *buf, size_t count)
{
	unsigned long enable;

	if (kstrtoul(buf, 0, &enable) < 0)
		return -EINVAL;

	if (enable != 0 && enable != 1)
		return -EINVAL;

	vm_expand_signal_enable = enable;
	return count;
}

static struct kobj_attribute ulimit_vm_attribute =
			__ATTR(vm_expand_signal_enable, 0640, show, store);

static struct attribute *attrs[] = {
	&ulimit_vm_attribute.attr,
	NULL,
};

static struct attribute_group attr_group = {
	.attrs = attrs,
};

static int ulimit_obj_init(void)
{
	int retval;

	ulimit_kobj = kobject_create_and_add("ulimit", mm_kobj);
	if (!ulimit_kobj)
		return -ENOMEM;

	retval = sysfs_create_group(ulimit_kobj, &attr_group);

	return retval;
}

static void ulimit_obj_exit(void)
{
	sysfs_remove_group(ulimit_kobj, &attr_group);
	kobject_put(ulimit_kobj);
}

module_init(ulimit_obj_init);
module_exit(ulimit_obj_exit);
MODULE_LICENSE("GPL");
